﻿#region Copyright(C) 2018 FI Ltd. All rights reserved.
// ==================================================================================================
// Copyright(C) 2018 FI Ltd. All rights reserved.
//
// SYSTEM NAME      : FI.Net Application Framework
// COMPONENT ID     : ApplicationContext
// COMPONENT DESC   : Session based contextual data sharing.
//
// CREATED DATE/BY  : 18 Aug 2018 / Tian Mi
//
// REVISION HISTORY :
// DATE/BY            SR#/CS/PM#/OTHERS      DESCRIPTION OF CHANGE
// ==================================================================================================
#endregion

using System;
using System.Runtime.Serialization;
using FI.Core.Properties;
using FI.Core.Utilities;

namespace FI.Core.ApplicationContexts
{
    /// <summary>
    /// define the context item's properties.
    /// </summary>
    [Serializable]
    [DataContract(Namespace=ApplicationContext.ContextHeaderNamespace)]
    public class ContextItem
    {
        #region Fields
        private object value;
        #endregion

        #region Properties

        /// <summary>
        /// Can be considered the unique name of the context item in the collection.
        /// </summary>
        [DataMember(Name="Key",IsRequired=true,Order=1)]
        public string Key { get; private set; }
        
        /// <summary>
        /// The value of the context item.
        /// </summary>
        [DataMember(Name = "Value", IsRequired = true, Order = 2)]
        public object Value
        {
            get
            {
                return value;
            }
            set
            {
                if (this.ReadOnly)
                {
                    throw new InvalidOperationException(ResourceUtility.Format(Resources.ExceptionCannotModifyReadonlyValue));
                }
                this.value = value;
            }
        }

        /// <summary>
        /// Indicates whether the context item is read-only or writable, and the default value is false.
        /// </summary>
        [DataMember(Name = "ReadOnly", IsRequired = true, EmitDefaultValue = true, Order = 3)]
        public bool ReadOnly { get; set; }
        
        /// <summary>
        /// Gets or sets a value indicating whether this instance is local.
        /// </summary>
        /// <value><c>true</c> if this instance is local; otherwise, <c>false</c>.</value>
        public bool IsLocal { get; private set; }

        /// <summary>
        ///The extended property collection bound to the context item.
        /// </summary>
        [DataMember(Name = "ExtendedProperties", IsRequired = false, EmitDefaultValue = false)]
        public ExtendedPropertyCollection ExtendedProperties { get; private set; }
        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ContextItem" /> class.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        /// <param name="isLocal">if set to <c>true</c> [is local].</param>
        public ContextItem(string key, object value,  bool isLocal)
        {
            Guard.ArgumentNotNullOrEmpty(key, "key");
            Guard.ArgumentNotNull(value, "value");

            this.Key = key;
            this.Value = value;
            this.IsLocal = isLocal;
            this.ExtendedProperties = new ExtendedPropertyCollection(this);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="ContextItem"/> class.
        /// </summary>
        /// <param name="key">The key.</param>
        /// <param name="value">The value.</param>
        public ContextItem(string key, object value)
            : this(key, value, false)
        { }
        #endregion
    }
}